package com.example.temp;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerAndConsumer {


    public class Storage {

        //最大容量  内部类不能声明静态变量
        public int MAX_SIZE = 30;
        //容器 存储媒介
        LinkedList<Integer> list = new LinkedList<>();

        ReentrantLock lock = new ReentrantLock();

        private Condition condition = lock.newCondition();

        public void produceLock() throws InterruptedException {
            lock.lock();
            while (list.size() == MAX_SIZE) {
                System.out.println("仓库已满，生产者" + Thread.currentThread().getName() + "不可生产.");
                condition.await();
            }
            list.add(1);
            System.out.println("生产者" + Thread.currentThread().getName() + "生产一个产品，现库存" + list.size());
            condition.signalAll();
        }
        public synchronized void produce() throws InterruptedException {
            while (list.size() == MAX_SIZE) {
                System.out.println("仓库已满，生产者" + Thread.currentThread().getName() + "不可生产.");
                this.wait();
            }
            list.add(1);
            System.out.println("生产者" + Thread.currentThread().getName() + "生产一个产品，现库存" + list.size());
            this.notifyAll();
        }

        public synchronized void consume() throws InterruptedException {

            while (list.size() == 0) {
                System.out.println("消费者" + Thread.currentThread().getName() + "仓库为空");
                this.wait();
            }

            list.removeFirst();
            System.out.println("消费者" + Thread.currentThread().getName() + "消费一个产品，现库存" + list.size());
            this.notifyAll();
        }
    }

    class Producer implements Runnable {

        private Storage storage;

        public Producer(Storage storage) {
            this.storage = storage;
        }

        @Override
        public void run() {

            while (true) {

                try {
                    storage.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }

        }
    }

    class Consumer implements Runnable {

        private Storage storage;

        public Consumer(Storage storage) {
            this.storage = storage;
        }

        @Override
        public void run() {

            while (true) {

                try {
                    storage.consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }


    public static void main(String[] args) {

        Storage storage = new ProducerAndConsumer().new Storage();
        Thread p1 = new Thread(new ProducerAndConsumer().new Producer(storage));
//        Thread p2 = new Thread(new ProducerAndConsumer().new Producer());

        Thread c1 = new Thread(new ProducerAndConsumer().new Consumer(storage));
//        Thread c2 = new Thread(new ProducerAndConsumer().new Consumer());
        p1.start();
//        p2.start();
        c1.start();
//        c2.start();
    }
}
